package day05;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import util.CookieUtil;
import util.JdbcUtil;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

@WebServlet("*.order")
public class OrderServlet extends HttpServlet {
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String path = request.getServletPath();

        if ("/create.order".equals(path)) {
            create(request, response);
        }

        if ("/findByUserId.order".equals(path)) {
            findByUserId(request, response);
        }

        if ("/findByOrderId.order".equals(path)) {
            findByOrderId(request, response);
        }
    }

    protected void create(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("OrderServlet.create()");

        String no=null;
        Integer orderId=null;

        HttpSession session=request.getSession();
        User user= (User) session.getAttribute("user");
        Cart cart= (Cart) session.getAttribute("cart");

        Connection con=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try{
            con= JdbcUtil.getConnection();
            con.setAutoCommit(false);

            String sql=new StringBuffer()
                    .append("insert into t_order ")
                    .append("    (no,create_date,user_id,price) ")
                    .append("values ")
                    .append("    (?,?,?,?) ")
                    .toString();

            ps=con.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);

            ps.setString(1,no=getNo());
            ps.setDate(2,new java.sql.Date(new Date().getTime()));
            ps.setInt(3,user.getId());
            ps.setDouble(4,cart.getPrice());

            ps.executeUpdate();

            rs=ps.getGeneratedKeys();

            if(rs.next()){
                orderId=rs.getInt(1);
            }

            rs.close();
            ps.close();


            sql=new StringBuffer()
                    .append("insert into t_item ")
                    .append("    (product_id,num,price,order_id) ")
                    .append("values ")
                    .append("    (?,?,?,?) ")
                    .toString();

            ps=con.prepareStatement(sql);

            List<Item> items=cart.getItems();

            for (Item item : items) {
                ps.setInt(1,item.getProduct().getId());
                ps.setInt(2,item.getNum());
                ps.setDouble(3,item.getPrice());
                ps.setInt(4,orderId);
//                ps.executeUpdate();
                ps.addBatch();
            }
            ps.executeBatch();


            con.commit();
        }catch (Exception e){
            e.printStackTrace();
            try {
                con.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }finally{
            JdbcUtil.close(rs,ps,con);
        }

        session.setAttribute("cart",new Cart());

//        session.setAttribute("no",no);

//        CookieUtil.addCookie("no",no,600,response);

//        response.sendRedirect(request.getContextPath()+"/shop/success.jsp");

        response.sendRedirect(request.getContextPath()+"/shop/success.jsp?no="+no);

    }

    protected void findByUserId(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("OrderServlet.findByUserId()");

        User user= (User) request.getSession().getAttribute("user");

        List<Order> orders=new ArrayList<>();
        Connection con=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try{
            con= JdbcUtil.getConnection();
            con.setAutoCommit(false);


            String sql=new StringBuffer()
                    .append("select * ")
                    .append("from t_order ")
                    .append("where user_id=? ")
                    .toString();

            ps=con.prepareStatement(sql);

            ps.setInt(1,user.getId());

            rs=ps.executeQuery();

            while(rs.next()){
                Order order=new Order();
                order.setId(rs.getInt("id"));
                order.setNo(rs.getString("no"));
                order.setCreateDate(rs.getDate("create_date"));
                orders.add(order);
            }

            con.commit();
        }catch (Exception e){
            e.printStackTrace();
            try {
                con.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }finally{
            JdbcUtil.close(rs,ps,con);
        }

        request.setAttribute("orders",orders);
        request.getRequestDispatcher("/shop/myOrders.jsp").forward(request,response);
    }

    protected void findByOrderId(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("OrderServlet.findByOrderId()");

        Integer orderId=Integer.parseInt(request.getParameter("orderId"));

        Order order=null;

        Connection con=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try{
            con= JdbcUtil.getConnection();
            con.setAutoCommit(false);


            String sql=new StringBuffer()
                    .append("select    o.id, ")
                    .append("          o.no, ")
                    .append("          o.price, ")
                    .append("          (select count(1) ")
                    .append("           from t_item item ")
                    .append("           where item.order_id=o.id) \"o.count\", ")
                    .append("          u.id, ")
                    .append("          u.username, ")
                    .append("          i.id, ")
                    .append("          i.num, ")
                    .append("          i.price, ")
                    .append("          p.id, ")
                    .append("          p.name ")
                    .append("from      t_order o ")
                    .append("left join t_user u ")
                    .append("	on o.user_id=u.id ")
                    .append("left join t_item i ")
                    .append("	on i.order_id=o.id ")
                    .append("left join t_product p ")
                    .append("	on i.product_id=p.id ")
                    .append("where o.id=? ")
                    .toString();

            ps=con.prepareStatement(sql);

            ps.setInt(1,orderId);

            rs=ps.executeQuery();

            //每次循环时一条记录
            while(rs.next()){
                //多次循环封装成一个订单对象，一个用户对象
                if(order==null){
                    order=new Order();
                    order.setId(rs.getInt("o.id"));
                    order.setNo(rs.getString("o.no"));
                    order.setPrice(rs.getDouble("price"));
                    order.setCount(rs.getInt("o.count"));

                    User user=new User();
                    user.setId(rs.getInt("id"));
                    user.setUsername(rs.getString("username"));

                    order.setUser(user);
                }

                if(rs.getInt("i.id")==0){
                    break;
                }


                //每次循环封装成一个商品对象，一个明细对象
                Product product=new Product();
                product.setId(rs.getInt("p.id"));
                product.setName(rs.getString("p.name"));

                Item item=new Item();
                item.setId(rs.getInt("i.id"));
                item.setNum(rs.getInt("i.num"));
                item.setPrice(rs.getDouble("i.price"));

                item.setProduct(product);
                order.addItem(item);
            }

            con.commit();
        }catch (Exception e){
            e.printStackTrace();
            try {
                con.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }finally{
            JdbcUtil.close(rs,ps,con);
        }

        request.setAttribute("order",order);
        request.getRequestDispatcher("/shop/myOrder.jsp").forward(request,response);
    }

    private synchronized String getNo(){
        Random random=new Random();
        return new Date().getTime()+String.format("%06d",random.nextInt(1000000));
    }



}
